<?php
/**
 * GeoContexter
 * @link http://code.google.com/p/geocontexter/
 * @package GeoContexter
 */

/**
 * Upload file in folder
 *
   USAGE:
   <pre>
   $file = new Geocontexter_Model_FileUpload;

   $params  = array('post_name'   => string,  // as defined in $_FILES
                    'data_folder' => string   // full path to the image directory
                    );

   $result  = $file->upload( $params );

   if($result instanceof Mozend_ModelError)
   {
       return $this->error( $result->getErrorString(), __file__, __line__ );
   }

   </pre>
 * @package GeoContexter
 * @subpackage Module_Geocontexter
 * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
 * @author Armand Turpel <geocontexter@gmail.com>
 * @version $Rev: 768 $ / $LastChangedDate: 2010-12-16 16:11:56 +0100 (jeu., 16 déc. 2010) $ / $LastChangedBy: armand.turpel $
 */

namespace Geocontexter\Model;

use Zend\Form\Element;
use Zend\Form\Form;

class FileUpload extends Form
{
    /**
     * upload image
     */
    public function run( $params )
    {
        try
        {
            $this->ServiceLocator = $params['ServiceLocator'];
            $this->request = $params['request'];

            $data = $this->_upload($params['target'], $params['post_name'], $params['form_name']);

            $this->validate_params( $params );

            $this->path  = $params['data_folder'];

            // test if image upload
            //
            if (empty($data['item_file']['tmp_name']) || empty($data['item_file']['name'])) {
                throw new \Exception('Upload file failed. Uploaded file dosent exists in $_FILES');
            }

            $this->create_files_folder( $params['data_folder'] );

            $data['item_file']['name'] = preg_replace('/[^a-zA-Z0-9_\- \.\pL]/u', '', $data['item_file']['name']);

            if (false === copy ( $data['item_file']['tmp_name'] ,
                                 $params['data_folder'] . '/' . $data['item_file']['name'] ) ) {
                throw new \Exception('Upload file failed. Coulnt copy file to: ' . $params['data_folder'] . '/files/' . $data['item_file']['name']);
            }

            return $data['item_file'];

        } catch(\Exception $e) {
            $this->removeFile();
            throw $e;
        }
    }



    /**
     * validate parameters
     *
     * @param array $params
     */
    private function validate_params( & $params )
    {
        if (!isset($params['post_name'])) {
            throw new \Exception('post_name field isnt defined');
        }

        if (false === is_string($params['post_name']))  {
            throw new \Exception('post_name isnt from type string');
        }

        if (!isset($params['data_folder'])) {
            throw new \Exception('data_folder isnt defined');
        }
    }

    /**
     * upload lists backup file for import
     */
    public function _upload($target, $file_input_name, $form_name)
    {
        $upload = $this->ServiceLocator->get('CoreUploadForm');
        $upload->init($target, $file_input_name, $form_name);

        if ($this->request->isPost()) {
            // Make certain to merge the files info!
            $post = array_merge_recursive(
                $this->request->getPost()->toArray(),
                $this->request->getFiles()->toArray()
            );

            $upload->form->setData($post);
            if ($upload->form->isValid()) {

                return $upload->form->getData();
            }
        }
        return false;
    }

    /**
     *
     */
    private function create_files_folder( $path )
    {
        if (!is_dir($path))  {
            $oldumask = umask(0);

            if (false === mkdir($path, 0777)) {
                umask($oldumask);
                throw new \Exception('Couldnt create directory: ' . $path);
            }

            umask($oldumask);
        }
    }

    /**
     *
     */
    public function removeFile()
    {
        if (isset($this->path)) {
            if (file_exists( $this->path . '/files/' . $this->_file['name'] )) {
                if (false === unlink($this->path . '/files/' . $this->_file['name'])) {
                    throw new \Exception('Error: Couldnt remove file: ' . $this->path . '/files/' . $this->_file['name']);
                }
            }
        }
    }
}